package com.itheima.app.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.domain.db.Deblocking;
import com.itheima.domain.db.Freeze;
import com.itheima.domain.db.User;
import com.itheima.service.db.DeblockingService;
import com.itheima.service.db.FreezeService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.Map;

@Component //放入到容器
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Reference
    private FreezeService freezeService;

    @Reference
    private DeblockingService deblockingService;

    //放行前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //获得token
        String token = request.getHeader("Authorization");
        //判断token是否有值
        if(StrUtil.isEmpty(token)){
            //返回权限不足(401)
            response.setStatus(401);
            return false;
        }

        //判断值是否过期
        Boolean flag = stringRedisTemplate.hasKey(ConstantUtil.USER_TOKEN + token);

        if(!flag){
            //token已经过期了
            //返回权限不足(401)
            response.setStatus(401);
            return false;
        }

        //解析token
        //解析token形成map
        Map map = JwtUtil.parseToken(token);
        //将map转换成对象
        User user = BeanUtil.mapToBean(map, User.class, true);
        //user解析错误 权限不足
        if(user == null){
            response.setStatus(401);
            return false;
        }





        //获取用户冻结信息
        Freeze freeze = freezeService.findByUser(user.getId());

        //查询用户解冻信息
        Deblocking deblocking = deblockingService.findByUserId(user.getId());


        //冻结信息不为空
        if (freeze!=null){

            //冻结数据放入redis
            if(freeze.getFreezingRange()==1){


                //冻结登录

                //如果解冻表有数据则 删除解冻数据
                if(deblocking!=null){
                    deblockingService.deleteByUserId(user.getId());
                }


                switch (freeze.getFreezingTime()){
                    case 1:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_LOGIN+user.getId(),"1", Duration.ofDays(3));
                        break;
                    case 2:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_LOGIN+user.getId(),"1", Duration.ofDays(7));
                        break;
                    case 3:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_LOGIN+user.getId(),"1");
                        break;
                    default: throw  new RuntimeException();

                }


            }else if(freeze.getFreezingRange()==2){
                //冻结发言

                deblockingService.deleteByUserId(user.getId());

                switch (freeze.getFreezingTime()){
                    case 1:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_SAY+user.getId(),"1", Duration.ofDays(3));
                        break;
                    case 2:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_SAY+user.getId(),"1", Duration.ofDays(7));
                        break;
                    case 3:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_SAY+user.getId(),"1");
                        break;
                    default: throw  new RuntimeException();

                }


            }else{
                //冻结发布动态
                deblockingService.deleteByUserId(user.getId());

                switch (freeze.getFreezingTime()){
                    case 1:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_MOVEMENT+user.getId(),"1", Duration.ofDays(3));
                        break;
                    case 2:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_MOVEMENT+user.getId(),"1", Duration.ofDays(7));
                        break;
                    case 3:
                        stringRedisTemplate.opsForValue().set(ConstantUtil.FREEZE_USER_MOVEMENT+user.getId(),"1");
                        break;
                    default: throw  new RuntimeException();

                }
            }

        }

        //解冻信息不为空
        if (deblocking!=null){

            //如果解冻数据存在则删除redis冻结数据
            //在登陆的时候判断了是否解冻登录

            //删除发言冻结
            stringRedisTemplate.delete(ConstantUtil.FREEZE_USER_SAY+user.getId());
            //删除发表动态冻结
            stringRedisTemplate.delete(ConstantUtil.FREEZE_USER_MOVEMENT+user.getId());
        }




        //如果被冻结 删除token
        flag = stringRedisTemplate.hasKey(ConstantUtil.FREEZE_USER_LOGIN+user.getId());

        if(flag){

            stringRedisTemplate.delete(ConstantUtil.USER_TOKEN + token);
            //返回权限不足(401)
            response.setStatus(401);
            return false;
        }

        //5.此次操作 token有效
        //绑定到线程上
        UserHolder.set(user);

        //6.续期
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token , "1" , Duration.ofDays(7));

        //7.放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserHolder.remove();//删除线程的绑定
    }
}
